﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
using FxSuperCore.Log;
using FxSuperCore.Utils;
using FxWinSuper.Functions;
using FxWinSupper.Config;

namespace FxWinSuper.UI.Menu.Pages
{
	/// <summary>
	/// LogPage.xaml 的交互逻辑
	/// </summary>
	internal partial class LogPage : Page
	{
		public LogPage()
		{
			InitializeComponent();
			InitView();
		}

		// 日志记录当前最大行数
		private const int MaxLogLine = 2000;

		// 所有日志级别
		private ObservableCollection<LogLevel> LogLevels = new ObservableCollection<LogLevel>();
		
		// 日志保存天数
		private ObservableCollection<string> LogFileExistDays = new ObservableCollection<string>();

		// 日志过滤级别
		private List<string> FilterLogLevels = new List<string>();

		// 日志级别对应的颜色表
		private static ReadOnlyDictionary<LogLevel, Brush> logLevelColorDic = new ReadOnlyDictionary<LogLevel, Brush>(new Dictionary<LogLevel, Brush>()
		{
			[LogLevel.DEBUG] = new SolidColorBrush(Colors.DarkGray),
			[LogLevel.INFO] = new SolidColorBrush(Colors.Black),
			[LogLevel.TRAE] = new SolidColorBrush(Colors.Black),
			[LogLevel.WARNNING] = new SolidColorBrush(Colors.Orange),
			[LogLevel.ERROR] = new SolidColorBrush(Colors.Red)
		});

		private InternalLog Logger;

		private void InitView()
		{
			Logger = InternalLog.Instance;
			foreach (LogLevel level in Enum.GetValues(typeof(LogLevel)))
			{
				LogLevels.Add(level);
				FilterLogLevels.Add(level.ToString());
			}
			FilterLogLevels.Add("ALL");
			uiLogLevelComboBox.ItemsSource = LogLevels;
			uiLogLevelComboBox.SelectedIndex = (int)Conf.OutputLogLevel;
			uiFilterLogLevelComboBox.ItemsSource = FilterLogLevels;
			// 修改日志过滤选择框索引会自动触发事件加载一次全部log
			uiFilterLogLevelComboBox.SelectedIndex = FilterLogLevels.Count - 1;

			foreach (LogFileExistDay value in Enum.GetValues(typeof(LogFileExistDay)))
			{
				LogFileExistDays.Add(value.GetEnumDesc().Split(':')[0]);
			}
			uiLogExistComboBox.ItemsSource = LogFileExistDays;
			uiLogExistComboBox.SelectedIndex = (int)Conf.LogFileExistTimeType;
			Logger.OnPrintLog += AppendLogToUi;
		}

		private Paragraph GetNewParagraph(LogLevel level, string log)
		{
			Paragraph paragraph = new Paragraph() { Margin = new Thickness(0, 5, 0, 5) };
			paragraph.Inlines.Add(new Run(log) { Foreground = logLevelColorDic[level] });
			return paragraph;
		}

		private bool LogCanAppendToUi(LogLevel level)
		{
			LogLevel targetlevel;
			bool isAllLevel = !Enum.TryParse(uiFilterLogLevelComboBox.SelectedItem.ToString(), out targetlevel);
			return isAllLevel || level == targetlevel;
		}

		private void AppendLogToUi(LogLevel level, string logLine)
		{
			Dispatcher.Invoke(() =>
			{
				if (!LogCanAppendToUi(level))
				{
					return;
				}

				if (uiLogContent.Document.Blocks.Count >= MaxLogLine)
				{
					uiLogContent.Document.Blocks.Remove(uiLogContent.Document.Blocks.FirstBlock);
				}

				uiLogContent.Document.Blocks.Add(GetNewParagraph(level, logLine));
				uiLogContent.ScrollToEnd();
			});
		}

		private void UpdateLogLine()
		{
			ClearUiLogContent();
			foreach (KeyValuePair<LogLevel, string> logPair in Logger.GetCurrentLogs())
			{
				AppendLogToUi(logPair.Key, logPair.Value);
			}
		}

		private void ClearUiLogContent()
		{
			uiLogContent.Document.Blocks.Clear();
		}

		private void OnLogelLevelSelectedChanged(object sender, SelectionChangedEventArgs e)
		{
			Conf.OutputLogLevel = (LogLevel)uiLogLevelComboBox.SelectedIndex;
		}

		private void OnFilterLogelLevelSelectedChanged(object sender, SelectionChangedEventArgs e)
		{
			UpdateLogLine();
		}

		private void OnLogeFileExistDaySelectedChanged(object sender, SelectionChangedEventArgs e)
		{
			Conf.LogFileExistTimeType = (LogFileExistDay) uiLogExistComboBox.SelectedIndex;
		}

		private void LookHistoryLog(object sender, RoutedEventArgs e)
		{
			Logger.ShowLogDirectory();
		}

	}

	internal enum LogFileExistDay
	{
		[Description("三天:3*24*3600")]
		Day3,
		[Description("一周:7*24*3600")]
		Day7,
		[Description("两周:14*24*3600")]
		Day14,
		[Description("一月:30*24*3600")]
		Day30
	}
}
